Acknowledgment: Per usual, this assignment relied heavily on Carole’s tutorial.
library(tidyverse)
library(sf)
library(leaflet)
library(htmltools)
library(htmlwidgets)
library(raster)
library(gstat)
library(spatial)
london_boroughs <- st_read("https://skgrange.github.io/www/data/london_boroughs.json", quiet = TRUE) %>%
dplyr::select(name)
leaflet(london_boroughs) %>%
addProviderTiles(providers$Stamen.TonerLite) %>%
addPolygons(highlightOptions = highlightOptions(fillColor = "yellow",
fillOpacity = 1),
label = ~name,
weight = 1)
child_weight <- read.csv("child_weight_london.csv")
london_boroughs_weight <- left_join(london_boroughs,child_weight,by="name") %>%
mutate(healthy_weight_10_11 = case_when(is.na(healthy_weight_10_11) ~ round(mean(healthy_weight_10_11, na.rm = TRUE),1),
!is.na(healthy_weight_10_11) ~ healthy_weight_10_11))
Add labels and colors to indicate the percent of children age 10-11 with healthy weight
london_boroughs_weight$label <-
paste(london_boroughs_weight$name, "<br>",
london_boroughs_weight$healthy_weight_10_11, "% of children age 10-11 with healthy weight") %>%
lapply(htmltools::HTML)
bins <- seq(min(london_boroughs_weight$healthy_weight_10_11),
max(london_boroughs_weight$healthy_weight_10_11), by = 1)
pal <- colorNumeric("viridis",
domain = london_boroughs_weight$healthy_weight_10_11,
na.color = "#00000000")
leaflet(london_boroughs_weight) %>%
addProviderTiles(providers$Stamen.TonerLite) %>%
addPolygons(highlightOptions = highlightOptions(fillOpacity = 1),
label = ~label,
fillColor = ~pal(healthy_weight_10_11),
weight = 1, color = "black") %>%
addLegend(pal = pal,
values = ~healthy_weight_10_11,
bins = 3,
opacity = 0.7, title = "Percent of children age <br> 10-11 with healthy weight",
position = "bottomright")
europe_proj <- "+proj=lcc +lat_1=35 +lat_2=65 +lat_0=52 +lon_0=10 +x_0=4000000 +y_0=2800000 +ellps=GRS80 +units=m +no_defs"
WGS84 <- "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
borough_points <- st_centroid(
st_transform(london_boroughs_weight, crs = europe_proj)) %>%
st_transform(WGS84)
leaflet(borough_points) %>%
addProviderTiles(providers$Stamen.TonerLite) %>%
addCircles(label = ~label,
fillColor = ~pal(healthy_weight_10_11),
stroke = FALSE,
radius = 500,
fillOpacity = 1) %>%
addLegend(pal = pal,
values = ~healthy_weight_10_11,
bins = 3,
opacity = 0.7, title = "Percent of children age <br> 10-11 with healthy weight",
position = "bottomright")
borough_pts_sp <- borough_points %>%
st_transform(europe_proj) %>%
as_Spatial()
borough_poly_sp <- london_boroughs_weight %>%
st_transform(europe_proj) %>%
as_Spatial()
london_raster <- raster(borough_poly_sp, res=10)
gs <- gstat(formula=healthy_weight_10_11~1, locations=borough_pts_sp)
idw_interp <- interpolate(london_raster, gs)
## [inverse distance weighted interpolation]
idw_interp_clip <- mask(idw_interp, borough_poly_sp)
leaflet(borough_points) %>%
addProviderTiles(providers$Stamen.TonerLite) %>%
addRasterImage(idw_interp_clip, colors = pal, opacity = 0.8) %>%
addLegend(pal = pal,
values = ~healthy_weight_10_11,
bins = 3,
opacity = 0.7, title = "Percent of children age <br> 10-11 with healthy weight",
position = "bottomright")
Discuss which of these three methods is 1) most informative, 2) most interesting, 3) most appropriate to the data, and 4) best
These visualizations show the percent of children age 10-11 in London with a healthy weight by borough. The first visualization, the chloropleth, visually assigns the percent for that borough to the whole borough spatially. This figure provides visual clarity on the value for each borough. However, it leaves room for interpretation that the assigned value is the value for each spatial point in the borough, rather than the value for the borough as a whole. This figure is informative and easy to understand the values broadly, which I think may make it most appropriate to the data and interesting, as well.
The second visualization, the centroids, provides some important visual cues. By assigning the data to a point, it may make it easier to clarify that this is not the specific value at each point in the polygon. However, it may be misinterpreted that the point represents the value at that fixed spatial point but rather is an average for that borough polygon.
Finally, the third visualization, the heat map, interpolates to show how boundaries may be more porous. Additionally, it is easy to identify which areas of the city are hot or cold spots because the values are not confined to one per borough. A downside of this is that it may appear, for example, that a specific subsection of Richmond upon Thames is a cold spot when, in reality, this percent is for the entire borough. Additionally, since these percents are for children in a given borough, the interpolation does not necessarily represent valid data (e.g. it may be better to use interpolation when you have several data points of for percent of children with a healthy weight at different spatial points within the city or boroughs and want to interpolate to fill in the gaps).
Finally, while I do think there are some drawbacks to the chloropleth, I think this is the best given the data set and clarity of the image, as discussed above.